/**
 * 
 */
package com.wubo.sec.service.impl;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;

import com.wubo.common.util.Assert;
import com.wubo.common.util.CollectionUtils;
import com.wubo.common.util.ObjectUtils;
import com.wubo.sec.config.LangUtil;
import com.wubo.sec.event.AuthorityEvent;
import com.wubo.sec.log.LogHelper;
import com.wubo.sec.log.LogState;
import com.wubo.sec.model.Authority;
import com.wubo.sec.model.UrlResource;
import com.wubo.sec.service.IUrlResourceService;
import com.wubo.sec.util.ObjectDifferenceChecker;
import com.wubo.sec.util.UUID;
import com.wubo.spring.hibernate.BaseHibernateDao;

/**
 * @author wubo
 * @CreateDate 2010-8-3
 * @version 1.0.01
 */
@SuppressWarnings("unchecked")
public class UrlResourceService implements IUrlResourceService, ApplicationListener<ApplicationEvent>   {
	private BaseHibernateDao dao;
	
	public UrlResourceService(BaseHibernateDao dao){
		this.dao = dao;
	}
	
	public UrlResource get(String code) {
		return dao.get(UrlResource.class, code);
	}
	
	/* (non-Javadoc)
	 * @see com.asc.sf.service.IUrlResourceService#create(com.asc.sf.entity.UrlResource)
	 */
	public String create(UrlResource resource) {
		Assert.notNull(resource);
		
		if(resource.getCode() == null){
			resource.setCode(UUID.uuid());
		}
		
		String code = (String) dao.save(resource);
		
		afterAdd(resource);
		
		return code;
	}

	/* (non-Javadoc)
	 * @see com.asc.sf.service.IUrlResourceService#delete(com.asc.sf.entity.UrlResource)
	 */
	public void delete(UrlResource resource) {
		Assert.notNull(resource);
		
		dao.delete(resource);
		
		afterDelete(resource);
	}

	/* (non-Javadoc)
	 * @see com.asc.sf.service.IUrlResourceService#delete(java.lang.String[])
	 */
	public void delete(String[] codes) {
		Assert.notNull(codes);
		
		for(int i=0; i<codes.length; i++){
			UrlResource resource = get(codes[i]);
			
			dao.delete(resource);
			
			afterDelete(resource);
		}
	}

	/* (non-Javadoc)
	 * @see com.asc.sf.service.IUrlResourceService#findAll()
	 */
	public List<UrlResource> findAll() {
		return dao.find("from UrlResource u");
	}
	
	public List<UrlResource> find(String filter, Object... params) {
		return dao.find("select u from UrlResource u "+filter, params);
	}
	
	public List<UrlResource> findRunAs(String filter, Object... params) {
		return find(filter, params);
	}

	/* (non-Javadoc)
	 * @see com.asc.sf.service.IUrlResourceService#getSplitPage(int, int)
	 */
	public List<UrlResource> getSplitPage(int start, int limit, String filter, Object... params) {
		return dao.queryForPage(start, limit, "select u from UrlResource u "+filter, params);
	}

	public long getTotal(String filter, Object... params) {
		Long result = dao.queryForObject("select count(u.code) from UrlResource u "+filter, params); 
		return result;
	}
	
	/* (non-Javadoc)
	 * @see com.asc.sf.service.IUrlResourceService#update(com.asc.sf.entity.UrlResource)
	 */
	public UrlResource update(UrlResource resource) {
		Assert.notNull(resource);
		
		UrlResource old = get(resource.getCode());
		
		dao.update(resource);
		
		afterUpdate(old, resource);
		
		return resource;
	}

	/* (non-Javadoc)
	 * @see com.asc.sf.filter.IFilterResourceLoader#loadFilterResource()
	 */
	public Map<String, String> loadFilterResource() {
		String queryString = "select u from UrlResource u inner join u.auth";
		
		List<UrlResource> resources = dao.find(queryString);
		
		CollectionUtils.uniqueList(resources);
		
		Map<String, String> map = new LinkedHashMap<String, String>();
		
		
		for(int i=0; i<resources.size(); i++){
			UrlResource resource = resources.get(i);
			Authority auth = resource.getAuth();
			
			map.put(resource.getUrl(), auth.getCode());
		}
		
		return map;
	}
	
	public String getAuthCode(String urlCode) {
		return dao.queryForObject("select a.code from UrlResource u inner join u.auth a where u.code = ?", new Object[]{urlCode});
	}
	
	public void relate(String urlCode, String authCode) {
		UrlResource url = dao.get(UrlResource.class, urlCode);
		
		String authName = "";
		if(authCode != null){
			Authority auth = dao.get(Authority.class, authCode);
			
			authName = auth.getName();
			
			url.setAuth(auth);
		}else{
			url.setAuth(null);
		}
		
		dao.update(url);
		
		if(LogState.isLogCode()){
			LogHelper.actionLog(LangUtil.get("RelateURLAuth"), LangUtil.get("URLAuthDetail", urlCode+"("+url.getName()+")", authCode+"("+authName+")"));
		}else{
			LogHelper.actionLog(LangUtil.get("RelateURLAuth"), LangUtil.get("URLAuthDetail", url.getName(), authName));
		}
		
	}

	public void onApplicationEvent(ApplicationEvent event) {
		if(event instanceof AuthorityEvent){
			AuthorityEvent authEvent = (AuthorityEvent) event;
			if( authEvent.getType() == AuthorityEvent.DELETE ){
				dao.executeSQL("DELETE FROM SEC_URL_AUTH WHERE AUTH_REL = ?", authEvent.getEntity().getCode());
			}
		}
	}
	/*----- 记录日志 -----*/
	protected void afterAdd(UrlResource resource){
		LogHelper.actionLog(LangUtil.get("CreateURL"), 
				LangUtil.get("URLDetail", resource.getCode(), ObjectUtils.objToString(resource)));
	}
	
	protected void afterUpdate(UrlResource old, UrlResource resource){
		LogHelper.actionLog(LangUtil.get("UpdateURL"), 
				LangUtil.get("UpdateURLDetail", ObjectDifferenceChecker.check(old, resource)));
	}
	
	protected void afterDelete(UrlResource resource){
		LogHelper.actionLog(LangUtil.get("DeleteURL"), 
				LangUtil.get("URLDetail", resource));
	}
}
